#include <iostream>
#include <string>
#include "Reactor.hpp"
#include "Listener.hpp"
#include "Log.hpp"
#include "Common.hpp"
#include "NetCal.hpp"

static void Usage(std::string proc)
{
    std::cerr << "Usage: " << proc << " port" << std::endl;
}

int main(int argc, char* argv[])
{
    if(argc != 2)
    {
        Usage(argv[0]);
        exit(USAGE_ERR);
    }

    LogModule::ConsoleLogStrategy();
    uint16_t port = std::stoi(argv[1]);

    //Netcal模块
    std::shared_ptr<Cal> cal = std::make_shared<Cal>();

    //Protocol模块
    std::shared_ptr<Protocol> protocol = std::make_shared<Protocol>([&cal](Request& req) -> Response{
        LOG(LogLevel::DEBUG) << "回调到Cal...";
        return cal->Calculate(req);
    });

    std::shared_ptr<Connection> conn = std::make_shared<Listener>(port);
    conn->RegisterHandler([&protocol](std::string& buffer) -> std::string{
        LOG(LogLevel::DEBUG) << "进入到RegiterHandler...";
        std::string res_str;
        while(1)
        {
            std::string package;
            if(!protocol->Decode(buffer, &package))
                break;
            res_str += protocol->BuildResponse(package);
        }
        return res_str;
    });

    std::unique_ptr<Reactor> R = std::make_unique<Reactor>();

    R->AddConnection(conn);
    R->Loop();
    return 0;
}